<!--
 * @use: 
 * @description: 布局面板
 * @Author: vision
 * @Date: 2023-09-07 11:25:31
 * @FilePath: /shared/modules/src/components/v-pane/src/v-pane.vue
-->
<template>
  <div ref="paneRef" class="v-split-pane__pane" @click="onPaneClick($event, props.uid)" :style="state.style">
    <slot></slot>
  </div>
</template>
<script setup lang="ts">
  import { ref, inject, reactive, onMounted, onBeforeUnmount, computed, watch, watchEffect, nextTick } from 'vue'
  import { tool } from '@v-model/shared--utils'

  defineOptions({ name: 'v-pane' })

  interface paneProps {
    uid?: string
    size?: string | null
    minSize?: string | null
    maxSize?: string | null
    style?: CSSStyleValue | undefined
  }

  /*--------------------------------types--------------------------------*/
  import {
    // paneProps,
    paneState,
    // requestUpdate,
    onPaneAdd,
    onPaneRemove,
    onPaneClick,
    requestUpdate_key,
    onPaneRemove_key,
    onPaneAdd_key,
    onPaneClick_key,
  } from './type'
  import { formatSize } from './util'

  /*--------------------------------props--------------------------------*/

  const props = withDefaults(defineProps<paneProps>(), {
    uid: function () {
      return tool.guid()
    },
    size: null,
    minSize: '0%',
    maxSize: '100%',
    style: function () {
      return {
        'flex-shrink': 0,
      }
    },
  })
  //暴露属性

  /*--------------------------------state--------------------------------*/
  //const searchRef = ref<InstanceType<typeof Search> | null>(null)
  const paneRef = ref<HTMLElement | null>(null)

  const state = reactive(<paneState>{
    size: props.size,
    style: props.style,
  })
  //const instance = <ComponentInternalInstance>getCurrentInstance()

  /*--------------------------------inject--------------------------------*/

  const requestUpdate = inject(requestUpdate_key)
  const onPaneAdd = <onPaneAdd>inject(onPaneAdd_key)
  const onPaneRemove = <onPaneRemove>inject(onPaneRemove_key)
  const onPaneClick = <onPaneClick>inject(onPaneClick_key)
  /*--------------------------------defineEmits--------------------------------*/
  const emits = defineEmits(['update'])
  /*--------------------------------method--------------------------------*/
  const update = (style: object) => {
    state.style = [state.style, { ...style }]
    emits('update', style)
  }

  /*--------------------------------computed--------------------------------*/
  const sizeNumber = computed(() => {
    let _size = null
    if (props.size) {
      const sizeObj = formatSize(props.size)
      _size = sizeObj.value + sizeObj.unit
    }
    return _size
  })

  const stop = watchEffect(() => {
    let _size = null
    if (props.size) {
      const sizeObj = formatSize(props.size)
      _size = sizeObj.value + sizeObj.unit
      requestUpdate({ uid: props.uid, size: _size })
    }
  })
  nextTick(() => {
    stop()
  })

  const minSizeNumber = computed(() => {
    let _size = null
    if (props.minSize) {
      const sizeObj = formatSize(props.minSize)
      _size = sizeObj.value + sizeObj.unit
    }
    return _size
  })

  const maxSizeNumber = computed(() => {
    let _size = null
    if (props.maxSize) {
      const sizeObj = formatSize(props.maxSize)
      _size = sizeObj.value + sizeObj.unit
    }
    return _size
  })

  /*--------------------------------watch--------------------------------*/

  watch(
    () => sizeNumber,
    (size) => {
      requestUpdate({ uid: props.uid, size: size.value })
    },
    { deep: true, immediate: true }
  )

  watch(
    () => minSizeNumber,
    (min) => {
      requestUpdate({ uid: props.uid, min: min.value })
    },
    { deep: true, immediate: true }
  )

  watch(
    () => maxSizeNumber,
    (max) => {
      requestUpdate({ uid: props.uid, max: max.value })
    },
    { deep: true, immediate: true }
  )

  /*--------------------------------defineExpose--------------------------------*/
  const getStyle = () => {
    return state.style
  }
  defineExpose({ getStyle })

  /*--------------------------------hook--------------------------------*/
  onMounted(() => {
    if (paneRef.value) {
      const definePane = ref({
        ...props,
        el: paneRef.value,
        update,
      })
      onPaneAdd(definePane.value)
    }
  })
  onBeforeUnmount(() => {
    if (paneRef.value) {
      const definePane = ref({
        ...props,
        el: paneRef.value,
        update,
      })
      onPaneRemove(definePane.value)
    }
  })
</script>
